#################################################################################
### Title: Are People Willing to Trade Away Democracy for Desirable Outcomes? ###
### Authors: Jonathan A. Chu, Scott Williamson, Eddy S. F. Yeung              ###
### Content: Asian Barometer Surveys analysis                                 ###
### Date: September 20, 2025                                                  ###
#################################################################################

### Set-up ----
rm(list = ls())
setwd("~/Desktop/democracy_tradeoff/replication") # change to your own working directory

## Load the required packages
library(tidyverse)
library(estimatr)
library(haven)
library(survey)

## Generate a log file
library(logr)
options("logr.autolog" = TRUE)

# Open the log
lf <- log_open(file.path("log_ABS.log"))

# Send messages to the log
log_code()

## Read the datasets (downloaded from https://www.asianbarometer.org/datar?page=d10)
df_KOR <- read_dta("W6_Korea_Release_20241220.dta")
df_MNG <- read_dta("W6_Mongolia_Release_20241223.dta")
df_PHL <- read_dta("W6_Philippines_release_20240403.dta")
df_TWN <- read_dta("W6_Taiwan_EN_20240402.dta")
df_THA <- read_dta("W6_8_Thailand_Release_20250108.dta")
df_IDN <- read_dta("W6_Indonesia_release_20240402.dta")
df_VNM <- read_dta("W6_11_Vietnam_Release_20250117.dta")
df_KHM <- read_dta("W6_Cambodia_Release_20240819.dta")
df_AUS <- read_dta("W6_15_Australia_Release_20250305.dta")

### First look at the data ----
## Agree or disagree (4-point): As long as a government can solve our country's 
## economic problem, it does not matter if the government holds regular elections or not
table(df_KOR$q169) %>% prop.table() * 100
table(df_MNG$q169) %>% prop.table() * 100
table(df_PHL$Q169) %>% prop.table() * 100
table(df_TWN$Q169) %>% prop.table() * 100
table(df_THA$q169) %>% prop.table() * 100
table(df_IDN$Q169) %>% prop.table() * 100
table(df_VNM$q169) %>% prop.table() * 100
table(df_KHM$q169) %>% prop.table() * 100
table(df_AUS$q169) %>% prop.table() * 100

## Agree or disagree (4-point): As long as the government can maintain order and 
## stability in the country, it does not matter whether it is democratic or undemocratic
table(df_KOR$q171) %>% prop.table() * 100
table(df_MNG$q171) %>% prop.table() * 100
table(df_PHL$Q171) %>% prop.table() * 100
table(df_TWN$Q171) %>% prop.table() * 100
table(df_THA$q171) %>% prop.table() * 100
table(df_IDN$Q171) %>% prop.table() * 100
table(df_VNM$q171) %>% prop.table() * 100
table(df_KHM$q171) %>% prop.table() * 100
table(df_AUS$q171) %>% prop.table() * 100

## Justified or unjustified (4-point): Which if any of the following circumstances 
## do you think would justify the government's use of emergency powers to constrain
## individual rights and freedoms?
# b. An Economic Crisis that has caused the loss of many jobs
# c. Widespread Corruption that the president [PM] claims can only be reduced by increasing executive power
# d. A Security Crisis due to social unrest or terrorism
table(df_KOR$q172b) %>% prop.table() * 100
table(df_KOR$q172c) %>% prop.table() * 100
table(df_KOR$q172d) %>% prop.table() * 100

table(df_MNG$q172b) %>% prop.table() * 100
table(df_MNG$q172c) %>% prop.table() * 100
table(df_MNG$q172d) %>% prop.table() * 100

table(df_PHL$Q172b) %>% prop.table() * 100
table(df_PHL$Q172c) %>% prop.table() * 100
table(df_PHL$Q172d) %>% prop.table() * 100

table(df_TWN$Q172b) %>% prop.table() * 100
table(df_TWN$Q172c) %>% prop.table() * 100
table(df_TWN$Q172d) %>% prop.table() * 100

table(df_THA$q172b) %>% prop.table() * 100
table(df_THA$q172c) %>% prop.table() * 100
table(df_THA$q172d) %>% prop.table() * 100

table(df_IDN$Q172b) %>% prop.table() * 100
table(df_IDN$Q172c) %>% prop.table() * 100
table(df_IDN$Q172d) %>% prop.table() * 100

table(df_VNM$q172b) %>% prop.table() * 100
table(df_VNM$q172c) %>% prop.table() * 100
table(df_VNM$q172d) %>% prop.table() * 100

table(df_KHM$q172b) %>% prop.table() * 100
table(df_KHM$q172c) %>% prop.table() * 100
table(df_KHM$q172d) %>% prop.table() * 100

table(df_AUS$q172b) %>% prop.table() * 100
table(df_AUS$q172c) %>% prop.table() * 100
table(df_AUS$q172d) %>% prop.table() * 100

### Recoding variables ----
## Write a function that reverse-code the original variable and assign other values as NA
convert_var <- function(x) {
  recode_map <- c(4, 3, 2, 1)
  result <- rep(NA_real_, length(x))  # initialize a numeric vector with NA
  
  valid_indices <- which(x %in% 1:4)  # find valid positions
  result[valid_indices] <- recode_map[x[valid_indices]]  # apply mapping only to valid indices
  
  return(result)
}

## Recode the economic trade-off variable
df_KOR$econ <- convert_var(df_KOR$q172b)
df_MNG$econ <- convert_var(df_MNG$q172b)
df_PHL$econ <- convert_var(df_PHL$Q172b)
df_TWN$econ <- convert_var(df_TWN$Q172b)
df_THA$econ <- convert_var(df_THA$q172b)
df_IDN$econ <- convert_var(df_IDN$Q172b)
df_VNM$econ <- convert_var(df_VNM$q172b)
df_KHM$econ <- convert_var(df_KHM$q172b)
df_AUS$econ <- convert_var(df_AUS$q172b)

## Recode the corruption trade-off variable
df_KOR$corrupt <- convert_var(df_KOR$q172c)
df_MNG$corrupt <- convert_var(df_MNG$q172c)
df_PHL$corrupt <- convert_var(df_PHL$Q172c)
df_TWN$corrupt <- convert_var(df_TWN$Q172c)
df_THA$corrupt <- convert_var(df_THA$q172c)
df_IDN$corrupt <- convert_var(df_IDN$Q172c)
df_VNM$corrupt <- convert_var(df_VNM$q172c)
df_KHM$corrupt <- convert_var(df_KHM$q172c)
df_AUS$corrupt <- convert_var(df_AUS$q172c)

## Recode the security trade-off variable
df_KOR$security <- convert_var(df_KOR$q172d)
df_MNG$security <- convert_var(df_MNG$q172d)
df_PHL$security <- convert_var(df_PHL$Q172d)
df_TWN$security <- convert_var(df_TWN$Q172d)
df_THA$security <- convert_var(df_THA$q172d)
df_IDN$security <- convert_var(df_IDN$Q172d)
df_VNM$security <- convert_var(df_VNM$q172d)
df_KHM$security <- convert_var(df_KHM$q172d)
df_AUS$security <- convert_var(df_AUS$q172d)

### Analysis: calculating weighted means and standard errors ----
## Define the survey design
svy_KOR <- svydesign(ids = ~1, weights = ~w, data = df_KOR)
svy_MNG <- svydesign(ids = ~1, weights = ~w, data = df_MNG)
svy_PHL <- svydesign(ids = ~1, weights = ~w, data = df_PHL)
svy_TWN <- svydesign(ids = ~1, weights = ~w, data = df_TWN)
svy_THA <- svydesign(ids = ~1, weights = ~w, data = df_THA)
svy_IDN <- svydesign(ids = ~1, weights = ~w, data = df_IDN)
svy_VNM <- svydesign(ids = ~1, weights = ~w, data = df_VNM)
svy_KHM <- svydesign(ids = ~1, weights = ~w, data = df_KHM)
svy_AUS <- svydesign(ids = ~1, weights = ~w, data = df_AUS)

## Calculate weighted means and SEs for the economic trade-off variable
extract_econ_mean <- function(svy_country, country_name) {
  svy_obj <- svymean(~econ, design = svy_country, na.rm = TRUE)
  mean <- coef(svy_obj)  # extract the mean
  se <- SE(svy_obj)  # extract the standard error
  result_df <- data.frame(variable = "Economic Crisis", country = country_name, 
                          mean = mean, se = se, 
                          lower_CI = mean - 1.96*se, upper_CI = mean + 1.96*se)
  return(result_df)
}

df_mean_econ <- 
  rbind(extract_econ_mean(svy_KOR, "South Korea"),
        extract_econ_mean(svy_MNG, "Mongolia"),
        extract_econ_mean(svy_PHL, "Philippines"),
        extract_econ_mean(svy_TWN, "Taiwan"),
        extract_econ_mean(svy_THA, "Thailand"),
        extract_econ_mean(svy_IDN, "Indonesia"),
        extract_econ_mean(svy_VNM, "Vietnam"),
        extract_econ_mean(svy_KHM, "Cambodia"),
        extract_econ_mean(svy_AUS, "Australia"))
df_mean_econ <- rename(df_mean_econ, se = econ, lower_CI = econ.1, upper_CI = econ.2)

combined_mean <- mean(df_mean_econ$mean)
combined_se <- sqrt(sum(df_mean_econ$se^2) / 9)
combined_lower_CI <- combined_mean - 1.96*combined_se
combined_upper_CI <- combined_mean + 1.96*combined_se

df_mean_econ <- df_mean_econ %>% 
  add_row(variable = "Economic Crisis", country = "Overall",
          mean = combined_mean, se = combined_se,
          lower_CI = combined_lower_CI, upper_CI = combined_upper_CI)

## Calculate weighted means and SEs for the corruption trade-off variable
extract_corrupt_mean <- function(svy_country, country_name) {
  svy_obj <- svymean(~corrupt, design = svy_country, na.rm = TRUE)
  mean <- coef(svy_obj)  # extract the mean
  se <- SE(svy_obj)  # extract the standard error
  result_df <- data.frame(variable = "Widespread Corruption", country = country_name, 
                          mean = mean, se = se,
                          lower_CI = mean - 1.96*se, upper_CI = mean + 1.96*se)
  return(result_df)
}

df_mean_corrupt <- 
  rbind(extract_corrupt_mean(svy_KOR, "South Korea"),
        extract_corrupt_mean(svy_MNG, "Mongolia"),
        extract_corrupt_mean(svy_PHL, "Philippines"),
        extract_corrupt_mean(svy_TWN, "Taiwan"),
        extract_corrupt_mean(svy_THA, "Thailand"),
        extract_corrupt_mean(svy_IDN, "Indonesia"),
        extract_corrupt_mean(svy_VNM, "Vietnam"),
        extract_corrupt_mean(svy_KHM, "Cambodia"),
        extract_corrupt_mean(svy_AUS, "Australia"))
df_mean_corrupt <- rename(df_mean_corrupt, se = corrupt, lower_CI = corrupt.1, upper_CI = corrupt.2)

combined_mean <- mean(df_mean_corrupt$mean)
combined_se <- sqrt(sum(df_mean_corrupt$se^2) / 9)
combined_lower_CI <- combined_mean - 1.96*combined_se
combined_upper_CI <- combined_mean + 1.96*combined_se

df_mean_corrupt <- df_mean_corrupt %>% 
  add_row(variable = "Widespread Corruption", country = "Overall",
          mean = combined_mean, se = combined_se,
          lower_CI = combined_lower_CI, upper_CI = combined_upper_CI)

## Calculate weighted means and SEs for the security trade-off variable
extract_security_mean <- function(svy_country, country_name) {
  svy_obj <- svymean(~security, design = svy_country, na.rm = TRUE)
  mean <- coef(svy_obj)  # extract the mean
  se <- SE(svy_obj)  # extract the standard error
  result_df <- data.frame(variable = "Security Crisis", country = country_name, 
                          mean = mean, se = se,
                          lower_CI = mean - 1.96*se, upper_CI = mean + 1.96*se)
  return(result_df)
}

df_mean_security <- 
  rbind(extract_security_mean(svy_KOR, "South Korea"),
        extract_security_mean(svy_MNG, "Mongolia"),
        extract_security_mean(svy_PHL, "Philippines"),
        extract_security_mean(svy_TWN, "Taiwan"),
        extract_security_mean(svy_THA, "Thailand"),
        extract_security_mean(svy_IDN, "Indonesia"),
        extract_security_mean(svy_VNM, "Vietnam"),
        extract_security_mean(svy_KHM, "Cambodia"),
        extract_security_mean(svy_AUS, "Australia"))
df_mean_security <- rename(df_mean_security, se = security, lower_CI = security.1, upper_CI = security.2)

combined_mean <- mean(df_mean_security$mean)
combined_se <- sqrt(sum(df_mean_security$se^2) / 9)
combined_lower_CI <- combined_mean - 1.96*combined_se
combined_upper_CI <- combined_mean + 1.96*combined_se

df_mean_security <- df_mean_security %>% 
  add_row(variable = "Security Crisis", country = "Overall",
          mean = combined_mean, se = combined_se,
          lower_CI = combined_lower_CI, upper_CI = combined_upper_CI)

## Combine the data frames
df_mean <- rbind(df_mean_econ, df_mean_corrupt, df_mean_security)
df_mean$variable <- factor(df_mean$variable, 
                           levels = c("Widespread Corruption", "Economic Crisis",
                                      "Security Crisis"))
df_mean$country <- factor(df_mean$country,
                          levels = c("Overall", "Thailand", "South Korea", 
                                     "Cambodia", "Indonesia", "Australia", 
                                     "Philippines", "Taiwan", "Vietnam",
                                     "Mongolia"))
df_mean <- df_mean %>% 
  mutate(size = if_else(country == levels(country)[1], 4, 2),
         size_line = if_else(country == levels(country)[1], 1.5, 0.5))

### Analysis: visualizing the weighted means and standard errors ----
ggplot(df_mean, aes(x = variable, y = mean, color = country, shape = country)) +
  geom_point(aes(size = size), position = position_dodge(.12)) +
  geom_errorbar(width = 0, aes(ymin = lower_CI, ymax = upper_CI, size = size_line),
                position = position_dodge(.12)) +
  scale_color_manual(values = c("black", "gray80", "gray80", "gray80", "gray80", 
                                "gray80", "gray80", "gray80", "gray80", "gray80")) +
  scale_shape_manual(values = c(19, 15:18, 4:9)) +
  scale_size_identity() +
  xlab("Circumstance") +
  ylab("Extent to which the circumstance justifies constraining rights and freedoms\n(1 = not at all justified; 4 = very justified)") +
  theme_bw() +
  theme(text = element_text(color = "black", size = 15, family = "Times"),
        axis.text.x = element_text(color = "black", size = 14, face = "bold", family = "Times"),
        axis.text.y = element_text(size = 13, family = "Times"),
        legend.position = "bottom",
        legend.direction = "horizontal",
        legend.background = element_blank(),
        legend.box.background = element_rect(color = "black"),
        legend.title = element_blank(),
        legend.key.size = unit(3, "line"),
        legend.key.height = unit(0, "cm")) +
  guides(color = guide_legend(nrow = 2, byrow = TRUE))
ggsave("Figure 6.pdf", width = 10, height = 8)

## Close the log file
log_close()